<template>
  <div class="content">
    <el-button type="primary" size="mini" @click="isShowModel = true">添加根菜单</el-button>
    <el-button type="success" size="mini" @click="createCode">生成代码</el-button>
    <!-- 树结构 -->
    <el-tree
      style="margin-top: 20px"
      :data="menuList"
      node-key="id"
      default-expand-all>
      <div class="tree-item" slot-scope="{ node, data }">
        <div>
          {{data.name}}
          <el-tag size="mini" style="margin-left:10px">{{data.en_name}}</el-tag>
        </div>
        <div>
          <el-button type="primary" size="mini" @click.stop="addMenuChild(data)">添加子菜单</el-button>
          <el-button type="success" size="mini" @click.stop="handleEdit(data)">编辑</el-button>
          <el-button type="danger" size="mini" @click.stop="handleDelete(data.id)">删除</el-button>
        </div>
      </div>
    </el-tree>
    <!-- 添加/编辑 -->
    <el-dialog :title="userForm.id!=undefined?'修改菜单':'创建菜单'" :visible.sync="isShowModel" @close="closeModel" width="700px" :append-to-body="true">
      <el-form ref="ruleForm" :model="userForm" :rules="rules">
        <el-form-item label="菜单名称" prop="name">
          <el-input v-model="userForm.name" clearable style="width:300px" placeholder="请填写菜单名称"></el-input>
        </el-form-item>
        <el-form-item label="标识名称" prop="en_name">
          <el-input v-model="userForm.en_name" clearable style="width:300px" placeholder="请填写英文标识名称"></el-input>
        </el-form-item>
        <!-- 当只有一个子项的时候显示 -->
        <el-form-item label="仅有一级显示分级" v-if="isShowSwith">
          <el-switch v-model="userForm.isAlwaysShow" active-text="显示" inactive-text="隐藏"></el-switch>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="isShowModel = false">取 消</el-button>
        <el-button type="primary" @click="submitForm">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 菜单代码 -->
    <el-dialog title="菜单模版代码" :visible.sync="isShowCopyCode" width="700px" :append-to-body="true">
      <el-input type="textarea" :value="codeText" rows="20"></el-input>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" size="small" @click="copyText">复制代码</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data(){
    return {
      menuList: [], // 菜单列表
      isShowSwith: false,
      userForm: {
        name: '',
        en_nme: '',
        uid: 0,
        isAlwaysShow: false
      }, // 表单
      rules: {
        name: [{required: true,message: '请输入菜单名称',trigger: 'blur'}],
        en_name: [{required: true,message: '请输入英文标识名称',trigger: 'blur'}],
      }, // 表单验证
      isShowModel: false, // 是否显示创建/删除弹窗
      isShowCopyCode: false, // 是否显示菜单模版代码
      codeText: '' // 菜单模版代码
    }
  },
  created(){
    this.getMenuList()
  },
  methods: {
    // 获取菜单列表
    getMenuList(){
      this.axios.post('MENU_LIST').then(result => {
        this.menuList = result.data
      })
    },
    // 关闭弹窗
    closeModel(){
      this.userForm = {
        name: '',
        en_nme: '',
        uid: 0,
        isAlwaysShow: false
      }
      this.isShowSwith = false
    },
    // 打开编辑
    handleEdit(item){
      this.userForm = {
        id: item.id,
        name: item.name,
        en_name: item.en_name,
        isAlwaysShow: item.isAlwaysShow == 1 ? true : false
      }
      if(item.children.length == 1){
        this.isShowSwith = true
      }else{
        this.isShowSwith = false
      }
      this.isShowModel = true
    },
    // 创建/编辑
    submitForm(){
      this.$refs.ruleForm.validate(e => {
        if(!e) return;
        this.axios.post(this.userForm.id?'EDIT_MENU':'CREATE_MENU',this.userForm).then(() => {
          // 成功提示
          this.$message({
            type: 'success',
            message: this.userForm.id ? '修改成功' : '创建成功'
          })
          this.isShowModel = false
          this.getMenuList()
        })
      })
    },
    // 添加子菜单
    addMenuChild(item){
      this.isShowModel = true
      this.userForm.uid = item.id
    },
    // 删除菜单
    handleDelete(id){
      this.$confirm('您确定要删除该菜单？','提示',{
        confirmButtonText: '确定',
        canceButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.axios.post('DELETE_MENU',{id}).then(() => {
          this.$message({
            type: 'success',
            message: '删除成功'
          })
          this.getMenuList()
        })
      })
    },
    // 复制代码
    copyText(){
      this.$copyText(this.codeText).then(()=>{
        this.$message({
          type: 'success',
          message: '已复制到剪切板'
        })
      })
    },
    // 生成菜单代码
    createCode(){
      this.codeText = this.arrayStr(0,this.recursionMenu(this.menuList))
      this.isShowCopyCode = true
    },
    // 递归
    recursionMenu(item,num = 0,type = false){
      let index = num + 1
      let codeText = ''
      item.forEach((v) => {
        if(v.children.length > 0){
          if(v.children.length == 1){
            //特殊情况
            let str = ''
            if(v.isAlwaysShow == 1){
              str = this.alwaysShowStr(index) + this.metaStr(index,v.name,v.en_name)
            }
            let node = this.pathStr(index) + this.componentStr(index,false) + str + this.childrenStr(index,this.recursionMenu(v.children,index,true))
            codeText += this.objStr(index,node)
          }else{
            let node = this.pathStr(index) + this.componentStr(index,false) + this.metaStr(index,v.name) + this.childrenStr(index,this.recursionMenu(v.children,index,true))
            codeText += this.objStr(index,node)
          }
        }else{
          // 无子项的情况
          if(type){
            codeText += this.itemStr(index+1,v.name,v.en_name)
          }else{
            let node = this.pathStr(index) + this.componentStr(index,false) + this.childrenStr(index,this.itemStr(index+2,v.name,v.en_name))
            codeText += this.objStr(index,node)
          }
        }
      })
      return codeText
    },
    itemStr(index,title,auth){
      let node = this.pathStr(index) + this.componentStr(index,true) + this.nameStr(index) + this.metaStr(index,title,auth)
      return this.objStr(index,node)
    },
    childrenStr(num,item){
      let space = ''
      for(let i = 0;i<num;i++){
        space += '  '
      }
      return `${space}  children: [\n${item}\n  ${space}]`
    },
    arrayStr(num,txt){
      let space = ''
      for(let i = 0;i<num;i++){
        space += ' '
      }
      return `${space}[\n${txt}\n${space}]`
    },
    objStr(num,txt){
      let space = ''
      for(let i = 0;i<num;i++){
        space += '  '
      }
      return `${space}{\n${txt}\n${space}},\n`
    },
    pathStr(num){
      let space = ''
      for(let i = 0;i<num;i++){
        space += '  '
      }
      return `${space}  path: '/',\n`
    },
    alwaysShowStr(num){
      let space = ''
      for(let i = 0;i<num;i++){
        space += '  '
      }
      return `${space}  alwaysShow: true,\n`
    },
    metaStr(num,title,auth = ''){
      let space = ''
      for(let i = 0;i<num;i++){
        space += '  '
      }
      let str = `, auth: '${auth}'`
      return `${space}  meta: { title: '${title}', icon: ''${auth == '' ? '' : str} },\n`
    },
    nameStr(num){
      let space = ''
      for(let i = 0;i<num;i++){
        space += '  '
      }
      return `${space}  name: '',\n`
    },
    componentStr(num,type){
      let space = ''
      for(let i = 0;i<num;i++){
        space += '  '
      }
      let str = type ? `() => import('@/views/')` : 'Layout'
      return `${space}  component: ${str},\n`
    }
  }
}
</script>

<style>
.el-tree-node__content{
  height: 40px;
}
</style>

<style scoped lang="scss">
.content{
  padding: 15px 10px;
  .tree-item{
    width: 100%;
    display: flex;
    justify-content: space-between;
  }
}
</style>